﻿#ifndef __SS_XML_DATA_H__
#define __SS_XML_DATA_H__
#include "../ssCfgData.h"
#include "ssTinyxmlExpand.h"
#include "../../string/ssString.h"


namespace StarSeeker
{

//表基类
/*template<typename T>
class ssIXmlTable : public ssICfgTable<T>
{
public:
	typedef typename ssICfgTable<T>::iterator iterator;

	ssIXmlTable()
	{
	}
	~ssIXmlTable()
	{
	}
	//读文件
	virtual bool Read()
	{
		ssTinyxmlExpand xml;
		if (!xml.LoadXmlFromFile(m_path.c_str()))
		{
			printf("%s read error!\n", m_path.c_str());
			return false;
		}

		while (xml.GetChildNode())
		{
			T row;
			while (xml.GetAttribute())
			{
				ssICfgValue* val = row.GetValue();
				if (!val) break;

				m_path = xml.GetAttributeName();
				if (val->type == SS_CFG_DATA_INT8)
				{
					((ssCfgInt8*)val)->val = xml.GetIntAttribute();
				}
				else if(val->type == SS_CFG_DATA_INT32)
				{
					((ssCfgInt32*)val)->val = xml.GetIntAttribute();
				}
				else if (val->type == SS_CFG_DATA_STRING)
				{
					((ssCfgStr*)val)->val = xml.GetStringAttribute();
				}
				else if (val->type == SS_CFG_DATA_FLOAT)
				{
					((ssCfgFloat*)val)->val = (float)xml.GetDoubleAttribute();
				}
			}
			m_map.insert(std::pair<i32, T>(row.GetKey(), row));
		}
		AfterRead();
		return true;
	}
	virtual void AfterRead()
	{
	}
};*/

//双键表基类
template<typename T>
class ssIXmlTable : public ssICfgTable<T>
{
public:
	typedef ssICfgTable<T> BaseClass;
	typedef typename ssIXmlTable<T>::iterator iterator;

	ssIXmlTable()
	{
	}
	virtual~ssIXmlTable()
	{
	}
	//读文件
	virtual bool Read()
	{
		ssTinyxmlExpand xml;
		if (!xml.LoadXmlFromFile(BaseClass::m_path.c_str()))
		{
			printf("%s read error!\n", BaseClass::m_path.c_str());
			return false;
		}

		while (xml.GetChildNode())
		{
			T row;
			ssString tmpStr;
			while (xml.GetAttribute())
			{
				ssICfgValue* val = row.GetValue();
				if (!val) break;

				//tmpStr = xml.GetAttributeName();
				switch (val->type)
				{
				case SS_CFG_DATA_INT8:
					((ssCfgInt8*)val)->val = xml.GetIntAttribute();
					break;
				case SS_CFG_DATA_INT32:
					((ssCfgInt32*)val)->val = xml.GetIntAttribute();
					break;
				case SS_CFG_DATA_STRING:
					((ssCfgStr*)val)->val = xml.GetStringAttribute();
					break;
				case SS_CFG_DATA_FLOAT:
					((ssCfgFloat*)val)->val = (float)xml.GetDoubleAttribute();
					break;
				case SS_CFG_DATA_INT32_V:
				{
					tmpStr = xml.GetStringAttribute();
					ssString::StrElements_t v;
					tmpStr.StringSplit('|', v);
					for (u32 ii = 0; ii < v.Count(); ++ii)
					{
						((ssCfgVInt32*)val)->val.push_back(v[ii].ToInt32());
					}
				}
				break;
				case SS_CFG_DATA_STRING_V:
				{
					tmpStr = xml.GetStringAttribute();
					ssString::StrElements_t v;
					tmpStr.StringSplit('|', v);
					for (u32 ii = 0; ii < v.Count(); ++ii)
					{
						((ssCfgVStr*)val)->val.push_back(v[ii].GetString());
					}
				}
				break;
				case SS_CFG_DATA_FLOAT_V:
				{
					tmpStr = xml.GetStringAttribute();
					ssString::StrElements_t v;
					tmpStr.StringSplit('|', v);
					for (u32 ii = 0; ii < v.Count(); ++ii)
					{
						((ssCfgVFloat*)val)->val.push_back((float)v[ii].ToFloat());
					}
				}
				break;
				case SS_CFG_DATA_INT32_VV:
				{
					tmpStr = xml.GetStringAttribute();
					ssString::StrElementList_t vv;
					tmpStr.StringSplit('^', '|', vv);
					for (u32 ii = 0; ii < vv.Count(); ++ii)
					{
						std::vector<i32> v;
						for (u32 iii = 0; iii < vv[ii].Count(); ++iii)
						{
							v.push_back(vv[ii][iii].ToInt32());
						}
						((ssCfgVVInt32*)val)->val.push_back(v);
					}
				}
				break;
				case SS_CFG_DATA_STRING_VV:
				{
					tmpStr = xml.GetStringAttribute();
					ssString::StrElementList_t vv;
					tmpStr.StringSplit('^', '|', vv);
					for (u32 ii = 0; ii < vv.Count(); ++ii)
					{
						std::vector<std::string> v;
						for (u32 iii = 0; iii < vv[ii].Count(); ++iii)
						{
							v.push_back(vv[ii][iii].GetString());
						}
						((ssCfgVVStr*)val)->val.push_back(v);
					}
				}
				break;
				case SS_CFG_DATA_FLOAT_VV:
				{
					tmpStr = xml.GetStringAttribute();
					ssString::StrElementList_t vv;
					tmpStr.StringSplit('^', '|', vv);
					for (u32 ii = 0; ii < vv.Count(); ++ii)
					{
						std::vector<f32> v;
						for (u32 iii = 0; iii < vv[ii].Count(); ++iii)
						{
							v.push_back((float)vv[ii][iii].ToFloat());
						}
						((ssCfgVVFloat*)val)->val.push_back(v);
					}
				}
				break;
				case SS_CFG_DATA_INT32_HEX:
				{
					tmpStr = xml.GetStringAttribute();
					if (tmpStr.Size() > 2 && tmpStr[0] == '0' && tmpStr[1] == 'x')
					{
						i32 tmpVal = 0;
						//减去末尾的\0
						for (u32 i = 2; i < tmpStr.Size() - 1; i++)
						{
							tmpVal <<= 4;
							if (tmpStr[i] >= '0' && tmpStr[i] <= '9')
							{
								tmpVal += tmpStr[i] - '0';
								continue;
							}

							if (tmpStr[i] >= 'a' && tmpStr[i] <= 'f')
							{
								tmpVal += tmpStr[i] - 'a' + 10;
								continue;
							}

							if (tmpStr[i] >= 'A' && tmpStr[i] <= 'F')
							{
								tmpVal += tmpStr[i] - 'A' + 10;
								continue;
							}
						}

						((ssCfgInt32Hex*)val)->val = tmpVal;
					}
					else
					{
						((ssCfgInt32Hex*)val)->val = xml.GetIntAttribute();
					}
				}
				break;
				default:
					break;
				}
			}
			i64 key = row.GetKey();
			row.ClearTempData();
			BaseClass::m_map.insert(std::pair<i64, T>(key, row));
		}
		AfterRead();
		return true;
	}
	virtual void AfterRead()
	{
	}
};

}
#endif

//使用例子
/*class TestCfgRow : public ssICfgRow
{
public:
	SS_CFG_DATA_BEGIN
	SS_CFG_KEY(m_id)
	SS_CFG_DATA(m_icon)
	SS_CFG_DATA(m_open)
	SS_CFG_DATA_END(TestCfgRow)

	ssCfgInt	m_id;
	ssCfgStr	m_icon;
	ssCfgStr	m_open;
};
class TestCfg : public ssIXmlTable<TestCfgRow>
{
public:
	TestCfg()
	{
		m_path = "cfg/FootIcon.xml";
	}
};*/
